package com.yzs.core.base

import android.view.LayoutInflater
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.viewbinding.ViewBinding
import com.yzs.base.base.BaseActivity
import com.yzs.core.bean.NetworkViewState
import com.yzs.core.bean.PageStatus
import java.lang.reflect.ParameterizedType

/**
 *    author : yzs
 *    date   : 2022/1/1317:56
 *    desc   : java 继承该类 便捷使用 viewBinding、viewModel
 */
abstract class CoreJavaBaseVBVMActivity<VB : ViewBinding, VM : ViewModel> : BaseActivity() {
    lateinit var binding: VB
    lateinit var vm: VM

    override fun initViewBinding(): ViewBinding? {
        //返回当前类的父类的Type
        val type = this.javaClass.genericSuperclass
        if (type is ParameterizedType) { // 如果支持泛型
            try {
                // 获得泛型中的实际类型，可能会存在多个泛型，[0] 也就是获得 VB 的 type
                val clazz = type.actualTypeArguments[0] as Class<VB>
                val method = clazz.getMethod("inflate", LayoutInflater::class.java)
                // 方法调用，获得 ViewBinding 实例
                binding = method.invoke(null, layoutInflater) as VB
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
        return binding
    }

    /**
     * 子类一般不重写该方法，除非自己实现获取 vm
     */
    override fun initViewModel() {
        val type = this.javaClass.genericSuperclass
        if (type is ParameterizedType) { // 如果支持泛型
            try {
                // 获得泛型中的实际类型，可能会存在多个泛型，[1] 也就是获得 VM 的type
                val clazz = type.actualTypeArguments[1] as Class<VM>
                vm = getActivityViewModel(clazz)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    /**
     * 使用 viewBinding 加载布局
     * 子类可以不重写该方法返回 layoutId
     */
    override fun getLayoutId() = 0

    /**
     * 在基类统一处理加载框
     * 如果不需要统一处理，可以重写该方法 不调用 super
     */
    open fun setPageStateLoadingUI(viewStates: LiveData<NetworkViewState>) {
        viewStates.observeKtNoNull {
            when (it.pageStatus) {
                is PageStatus.LOADING -> showLoadingDialog()
                is PageStatus.SUCCESS -> dismissLoadingDialog()
                is PageStatus.FAILURE -> dismissLoadingDialog()
            }
        }
    }
}